Imports System
Imports System.Collections
Imports System.Configuration
Imports System.Data
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Xml
Imports Cdm.DataCore.AdHocReport

Partial Class AdHocReport_AdHocFinancial
    Inherits System.Web.UI.Page

    Dim selectedFields As IList
    Dim javaScriptBlank As String = "setOperandList('{0}','{1}')"
    Dim C_AD_HOC_REPORT_ID As Integer = 2
    Dim columnHash As Hashtable

    Private Property SortField() As String
        Get
            If ViewState("sortfield") Is Nothing Then
                ViewState("sortfield") = ""
            End If

            Return ViewState("sortfield").ToString()
        End Get
        Set(ByVal value As String)

        End Set
    End Property

    Private Property IsAscending() As Boolean
        Get
            If ViewState("isascending") Is Nothing Then
                ViewState("isascending") = False
            End If

            Return Convert.ToBoolean(ViewState("isascending"))
        End Get
        Set(ByVal value As Boolean)
            ViewState("isascending") = value
        End Set
    End Property

    Private Property PageIndex() As Integer
        Get
            If ViewState("pageindex") Is Nothing Then
                Return 1
            Else
                Return Convert.ToInt32(ViewState("pageindex"))
            End If
        End Get
        Set(ByVal value As Integer)
            ViewState("pageindex") = value
        End Set
    End Property

    Private ReadOnly Property SearchCriteria() As ArrayList
        Get
            If ViewState("searchcriteria") Is Nothing Then
                ViewState("searchcriteria") = New ArrayList
            End If

            Return CType(ViewState("searchcriteria"), ArrayList)
        End Get
    End Property

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        WarningLabel.Visible = False
        ErrorLabel.Visible = False        

        If (Not IsPostBack) Then

            BindGrid()
            BindFieldDropdownList()
            BindCheckBoxList()

            Me.DisplayAllCheckBox.Attributes.Add("onclick", "GrayOutCheckBoxList()")

        End If

        SetDropDownText(Me.AddOperatorDropDown, Me.AddFieldNameDropDown.SelectedValue.ToString())
        Me.AddFieldNameDropDown.Attributes.Add("onchange", String.Format(javaScriptBlank, AddFieldNameDropDown.ClientID, _
                                     AddOperatorDropDown.ClientID, AddValueTextBox.ClientID, "false"))
        Me.AddValueTextBox.Attributes.Add("onchange", String.Format(javaScriptBlank, AddFieldNameDropDown.ClientID, _
                                       AddOperatorDropDown.ClientID, AddValueTextBox.ClientID, "true"))

        RegisterJavaScript()

        Dim javascript As String = ""

        If columnHash Is Nothing Then
            columnHash = Cdm.DataCore.Custom.ColumnList.GetColumnList("vwParticipantDisplay")
        End If

        If (Not AddFieldNameDropDown Is Nothing) Then
            javascript = String.Format(javaScriptBlank, AddOperatorDropDown.ClientID, AddFieldNameDropDown.ClientID)
            AddFieldNameDropDown.Attributes.Add("onchange", javascript)
        End If
    End Sub

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.Accordion1.FindControl("nothing")
        Me.SearchCriteriaPane.FindControl("nothing")
    End Sub

    Private Sub BindGrid()
        Me.SearchCriteriaGridView.DataSource = Me.SearchCriteria
        SearchCriteriaGridView.DataBind()
    End Sub

    Private Function GetFinancialFields() As System.Collections.Generic.List(Of Cdm.DataCore.Admin.AdminRequiredField)
        Dim fieldList = Cdm.DataCore.Admin.AdminRequiredField.ListByTableID(14041)

        Return fieldList
    End Function

    Private Sub BindCheckBoxList()
        Me.ColumnsCheckBoxList.DataSource = GetFinancialFields()
        Me.ColumnsCheckBoxList.DataTextField = "FieldDisplayName"
        Me.ColumnsCheckBoxList.DataValueField = "FieldName"
        Me.ColumnsCheckBoxList.DataBind()
    End Sub

    Private Sub BindFieldDropdownList()
        Dim fieldArray As Generic.List(Of Cdm.DataCore.Admin.AdminRequiredField) = GetFinancialFields()

        Me.AddFieldNameDropDown.DataSource = fieldArray
        Me.AddFieldNameDropDown.DataTextField = "FieldDisplayName"
        Me.AddFieldNameDropDown.DataValueField = "FieldName"
        Me.AddFieldNameDropDown.DataBind()

        Me.SortOrder.DataSource = fieldArray
        Me.SortOrder.DataTextField = "FieldDisplayName"
        Me.SortOrder.DataValueField = "FieldName"
        Me.SortOrder.DataBind()

        Dim savedReportsList As Generic.List(Of Cdm.DataCore.AdHocReport.AdHocUserReport)
        savedReportsList = Cdm.DataCore.AdHocReport.AdHocUserReport.ListByUserId(UserAuthorization.CurrentUser.UserId, C_AD_HOC_REPORT_ID)
        Me.SavedReportsDDL.DataSource = savedReportsList
        Me.SavedReportsDDL.DataTextField = "Description"
        Me.SavedReportsDDL.DataValueField = "AdHocUserReportId"
        Me.SavedReportsDDL.DataBind()
    End Sub

    Private Sub AttachControlEvents()
        AddHandler Me.AddButton.Click, AddressOf AddButton_Click
        AddHandler Me.PageSizeDropDown.SelectedIndexChanged, AddressOf PageSizeDropDown_SelectedIndexChanged
        AddHandler Me.SearchCriteriaGridView.RowDataBound, AddressOf SearchCriteriaGridView_RowDataBound
        AddHandler Me.SearchCriteriaGridView.RowDeleting, AddressOf SearchCriteriaGridView_RowDeleting
        'TODO(ConjunctionTypeRadioButtonList)
        AddHandler Me.SearchButton.Click, AddressOf SearchButton_Click
        AddHandler Me.SearchResultsGridView.PageIndexChanging, AddressOf SearchResultsGridView_PageIndexChanging
        AddHandler Me.ExportButton.Click, AddressOf ExportButton_Click
        'AddHandler Me.SaveColumnsButton.Click, AddressOf SaveColumnsButton_Click
    End Sub

    Sub PageSizeDropDown_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles PageSizeDropDown.SelectedIndexChanged
        Dim grdResult As GridView = CType(SearchResultsPane.FindControl("SearchResultsGridView"), GridView)
        grdResult.PageSize = Me.PageSizeDropDown.SelectedValue
        BindSearchResults("Search", Me.PageIndex)
    End Sub

    Private Sub SetDropDownText(ByVal opDDL As DropDownList, ByVal fieldName As String)

        columnHash = Cdm.DataCore.Custom.ColumnList.GetColumnList("vwFinancialHistory")
        Dim colType As String = columnHash(fieldName)

        Select Case colType
            Case "varchar"
                opDDL.Items(0).Text = "Equals"
                opDDL.Items(1).Text = "Starts With"
                opDDL.Items(2).Text = "Contains"
                opDDL.Style("disabled") = "false"
            Case "int"
                opDDL.Items(0).Text = "Equals"
                opDDL.Items(1).Text = "Less Than"
                opDDL.Items(2).Text = "Greater Than"
                opDDL.Style("disabled") = "false"
            Case "float"
                opDDL.Items(0).Text = "Equals"
                opDDL.Items(1).Text = "Less Than"
                opDDL.Items(2).Text = "Greater Than"
                opDDL.Style("disabled") = "false"
            Case "datetime"
                opDDL.Items(0).Text = "Equals"
                opDDL.Items(1).Text = "Less Than"
                opDDL.Items(2).Text = "Greater Than"
                opDDL.Style("disabled") = "false"
            Case "bit"
                opDDL.Items(0).Text = "Equals"
                opDDL.Style("disabled") = "true"
            Case Else
                opDDL.Items(0).Text = "Starts With"
                opDDL.Items(1).Text = "Equals"
                opDDL.Items(2).Text = "Contains"
                opDDL.Items(3).Text = "Less Than"
                opDDL.Items(4).Text = "Greater Than"
                opDDL.Style("disabled") = "false"
        End Select
    End Sub

    Private Function AllItemsChecked() As Boolean
        Dim i As Integer
        For i = 0 To Me.ColumnsCheckBoxList.Items.Count - 1
            If (Not Me.ColumnsCheckBoxList.Items(i).Selected) Then
                Return False
            End If
        Next
        Return True
    End Function

    Sub ExportButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ExportButton.Click
        Dim fileName As String = ""

        Try
            Dim directory As String = System.Web.Configuration.WebConfigurationManager.AppSettings("ExportDirectory").ToString()
            If (Not directory.EndsWith("//")) Then
                directory = String.Concat(directory, "//")
            End If

            Dim directoryAndFile As String = String.Concat(directory, "TrReport", UserAuthorization.CurrentUser.LogonId, ".xlsx")

            fileName = Server.MapPath(directoryAndFile)
        Catch ex As Exception
            DisplayError("Error getting export file name", ex)
        End Try

        CreateExport(fileName)
    End Sub

    Private Sub CreateExport(ByVal fileName As String)
        Dim searchResultsList As IList = New ArrayList()
        'TODO (DH) - put the resuls in an Excel spreadsheet

        Me.ExportingPanel.Visible = False
        Response.ContentType = "application/vnd.ms-excel"
        'Response.AppendHeader("Content-Disposition", "filename=Data.xlsx;");
        Response.AddHeader("Content-Disposition", "attachment;filename=TransactionReport.xlsx")
        Response.AddHeader("Target", "_blank")
        Response.WriteFile(fileName)
        Response.Flush()
        Response.End()
    End Sub

    Sub DisplayError(ByVal title As String, ByVal ex As Exception)
        ErrorLabel.Text = String.Concat(title, ":  ", ex.Message)
        ErrorLabel.Visible = True
    End Sub

    Sub SearchResultsGridView_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) Handles SearchResultsGridView.PageIndexChanging
        Me.SearchResultsGridView.PageIndex = e.NewPageIndex
        BindSearchResults("Search", e.NewPageIndex + 1)
    End Sub

    Sub SearchButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SearchButton.Click
        If (Me.SearchCriteria.Count = 0) Then
            WarningLabel.Visible = True
        Else
            BindSearchResults("Search", 1)
        End If
    End Sub

    Private Sub BindSearchResults(ByVal searchType As String, ByVal pageNumber As Integer)
        Dim recordCount As Integer = 0
        Dim resultsList As IList = GetSearchResultList()

        recordCount += resultsList.Count()

        Dim grdResult As GridView = CType(SearchResultsPane.FindControl("SearchResultsGridView"), GridView)
        grdResult.DataSource = resultsList
        grdResult.Columns.Clear()

        For iCol As Integer = 0 To Me.ColumnsCheckBoxList.Items.Count - 1
            If Me.DisplayAllCheckBox.Checked Then
                Dim newcol As New BoundField
                newcol.DataField = Me.ColumnsCheckBoxList.Items(iCol).Value
                newcol.HeaderText = Me.ColumnsCheckBoxList.Items(iCol).Text
                grdResult.Columns.Add(newcol)
            End If
            If Me.ColumnsCheckBoxList.Items(iCol).Selected Then
                Dim newcol As New BoundField
                newcol.DataField = Me.ColumnsCheckBoxList.Items(iCol).Value
                newcol.HeaderText = Me.ColumnsCheckBoxList.Items(iCol).Text
                grdResult.Columns.Add(newcol)
            End If
        Next

        grdResult.DataBind()
        grdResult.PageSize = Me.PageSizeDropDown.SelectedValue

        Dim firstRecord As Integer = (pageNumber - 1) * Convert.ToInt32(Me.PageSizeDropDown.SelectedValue) + 1
        Dim lastRecord As Integer = firstRecord + Convert.ToInt32(Me.PageSizeDropDown.SelectedValue) - 1
        If (lastRecord > recordCount) Then
            lastRecord = recordCount
        End If

        Me.ResultsCountLabel.Text = String.Format("Viewing items {0} to {1} of {2} total transactions", _
                                                    firstRecord.ToString(), lastRecord.ToString(), recordCount.ToString())
    End Sub

    Private Function GetSearchResultList() As IList

        RefreshCriteriaFromGrid()

        Me.Accordion1.SelectedIndex = 2
        Dim whereClause As String = GetWhereClause()
        Dim orderByClause As String = GetOrderByClause()

        'TODO: Update with AdHocQuery in appropriate data core class
        Dim resultsList As IList = Cdm.DataCore.Budget.FinancialHistory.AdHocQuery(whereClause, orderByClause)

        Return resultsList
    End Function

    Private Function GetWhereClause() As String
        Dim sbWhereClause As System.Text.StringBuilder = New System.Text.StringBuilder()
        Dim iClause As Integer
        For iClause = 0 To Me.SearchCriteria.Count - 1 Step iClause + 1
            If (Not String.IsNullOrEmpty(sbWhereClause.ToString())) Then
                sbWhereClause.Append(String.Concat(" ", "AND", " "))
            End If
            Dim sc As SearchCriterion = CType(SearchCriteria(iClause), SearchCriterion)
            sbWhereClause.Append(sc.WhereClause)
        Next

        Return sbWhereClause.ToString()
    End Function

    Private Function GetOrderByClause() As String
        Dim orderBy As String = Me.SortOrder.SelectedValue.ToString()
        Return orderBy
    End Function

    Private Function GetAuditWhereClause() As String
        Dim sbAuditClause As System.Text.StringBuilder = New System.Text.StringBuilder()
        Dim iClause As Integer
        For iClause = 0 To Me.SearchCriteria.Count - 1 Step iClause + 1
            If (Not String.IsNullOrEmpty(sbAuditClause.ToString())) Then
                sbAuditClause.Append(String.Concat(" ", " AND "))
            End If
            Dim sc As SearchCriterion = CType(SearchCriteria(iClause), SearchCriterion)
            sbAuditClause.Append(sc.AuditClause)
        Next

        Return sbAuditClause.ToString()
    End Function

    Sub SearchCriteriaGridView_RowDeleting(ByVal sender As Object, ByVal e As GridViewDeleteEventArgs) Handles SearchCriteriaGridView.RowDeleting
        RefreshCriteriaFromGrid()
        Me.SearchCriteria.RemoveAt(e.RowIndex)
        BindGrid()
    End Sub

    Sub SearchCriteriaGridView_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles SearchCriteriaGridView.RowDataBound
        Dim sc As SearchCriterion = CType(e.Row.DataItem, SearchCriterion)
        Dim FieldNameDropDown As DropDownList = CType(e.Row.FindControl("EditFieldNameDropDown"), DropDownList)
        Dim OperatorDropDown As DropDownList = CType(e.Row.FindControl("EditOperatorDropDown"), DropDownList)
        Dim FieldValueTextBox As TextBox = CType(e.Row.FindControl("EditValueTextBox"), TextBox)
        Dim AndOrLabel As Label = CType(e.Row.FindControl("AndOrLabel"), Label)
        Dim javascript As String = ""

        If columnHash Is Nothing Then
            columnHash = Cdm.DataCore.Custom.ColumnList.GetColumnList("vwParticipantDisplay")
        End If

        If (Not FieldNameDropDown Is Nothing) Then
            javascript = String.Format(javaScriptBlank, OperatorDropDown.ClientID, FieldNameDropDown.ClientID)
            FieldNameDropDown.Attributes.Add("onchange", javascript)
            'FieldNameDropDown.Attributes.Add("onchange", String.Format(javaScriptBlank, FieldNameDropDown.ClientID, _
            '                              OperatorDropDown.ClientID, FieldValueTextBox.ClientID, "false"))
            'OperatorDropDown.Attributes.Add("onchange", String.Format(javaScriptBlank, FieldNameDropDown.ClientID, _
            '                              OperatorDropDown.ClientID, FieldValueTextBox.ClientID, "true"))
            FieldNameDropDown.DataSource = GetFinancialFields()
            FieldNameDropDown.DataTextField = "FieldDisplayName"
            FieldNameDropDown.DataValueField = "FieldName"
            FieldNameDropDown.DataBind()
            FieldNameDropDown.SelectedValue = sc.FieldName
            SetDropDownText(OperatorDropDown, FieldNameDropDown.SelectedValue.ToString())
            OperatorDropDown.Items.FindByText(sc.Operand).Selected = True
            FieldValueTextBox.Text = sc.FieldValue
            If (e.Row.RowIndex > 0) Then
                AndOrLabel.Text = "AND"
            End If
        End If
    End Sub

    Private Sub RegisterJavaScript()
        Dim sb As New System.Text.StringBuilder()
        Dim fieldList As System.Collections.Generic.List(Of Cdm.DataCore.Admin.AdminRequiredField)

        columnHash = Cdm.DataCore.Custom.ColumnList.GetColumnList("vwFinancialHistory")

        fieldList = GetFinancialFields()

        sb.AppendLine("<script language='javascript'>")
        sb.AppendLine("function GetFieldType(fieldName)")
        sb.AppendLine("{")
        sb.AppendLine("")
        sb.AppendLine("switch(fieldName)")
        sb.AppendLine("{")

        For iFld As Integer = 0 To fieldList.count - 1
            Dim fieldName As String = fieldList(iFld).FieldName
            Dim colType As String = columnHash(fieldName)

            sb.AppendLine(String.Concat("   case '", fieldName, "':"))
            sb.AppendLine(String.Concat("       return '", colType, "';"))
        Next

        sb.AppendLine("    default:")
        sb.AppendLine("           return 'varchar';")
        sb.AppendLine("}")

        sb.AppendLine("}")
        sb.AppendLine("</script>")

        Me.javascriptLiteral.Text = sb.ToString()
    End Sub

    Private Sub RefreshCriteriaFromGrid()
        Dim iRow As Integer
        For iRow = 0 To SearchCriteriaGridView.Rows.Count - 1 Step iRow + 1
            Dim currRow As GridViewRow = SearchCriteriaGridView.Rows(iRow)
            Dim sc As SearchCriterion = CType(SearchCriteria(iRow), SearchCriterion)
            Dim FieldNameDropDown As DropDownList = CType(currRow.FindControl("EditFieldNameDropDown"), DropDownList)
            Dim OperatorDropDown As DropDownList = CType(currRow.FindControl("EditOperatorDropDown"), DropDownList)
            Dim FieldValueTextBox As TextBox = CType(currRow.FindControl("EditValueTextBox"), TextBox)

            If (Not FieldNameDropDown Is Nothing) Then
                sc.FieldName = FieldNameDropDown.SelectedValue
                sc.Operand = OperatorDropDown.SelectedItem.Text
                sc.FieldValue = FieldValueTextBox.Text
            End If
        Next
    End Sub

    Protected Sub AddButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AddButton.Click
        RefreshCriteriaFromGrid()
        Dim NewCriterion As SearchCriterion = New SearchCriterion()
        NewCriterion.FieldName = AddFieldNameDropDown.SelectedValue
        NewCriterion.Operand = AddOperatorDropDown.SelectedItem.Text
        NewCriterion.FieldValue = AddValueTextBox.Text
        NewCriterion.Id = Me.SearchCriteria.Count + 1
        Me.SearchCriteria.Add(NewCriterion)
        BindGrid()
    End Sub

    Protected Sub SaveButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveButton.Click
        Dim report As New Cdm.DataCore.AdHocReport.AdHocUserReport
        report.AdHocReportId = C_AD_HOC_REPORT_ID
        report.UserId = UserAuthorization.CurrentUser.UserId
        report.Description = ReportName.Text
        report.SortField = Me.SortField
        report.IsSortAscending = Me.IsAscending
        report.Persist()

        Cdm.DataCore.AdHocReport.AdHocUserReportCriterion.DeleteByUserReportId(report.AdHocUserReportId)

        For i As Integer = 0 To Me.SearchCriteria.Count() - 1
            Dim sc As SearchCriterion = CType(Me.SearchCriteria(i), SearchCriterion)
            Dim adHocCriterion As New Cdm.DataCore.AdHocReport.AdHocUserReportCriterion
            adHocCriterion.AdHocUserReportId = report.AdHocUserReportId
            adHocCriterion.FieldName = sc.FieldName
            adHocCriterion.FieldOperator = sc.Operand
            adHocCriterion.FieldValue = sc.FieldValue
            adHocCriterion.FieldOrder = i + 1
            adHocCriterion.Persist()
        Next

        Cdm.DataCore.AdHocReport.AdHocUserReportField.DeleteByUserReportId(report.AdHocUserReportId)

        For iCol As Integer = 0 To Me.ColumnsCheckBoxList.Items.Count - 1
            If Me.ColumnsCheckBoxList.Items(iCol).Selected Then
                Dim adHocUserReportField As New Cdm.DataCore.AdHocReport.AdHocUserReportField
                adHocUserReportField.AdHocUserReportId = report.AdHocUserReportId
                adHocUserReportField.FieldName = Me.ColumnsCheckBoxList.Items(iCol).ToString()
                adHocUserReportField.Persist()
            End If
        Next

        Me.SavedReportsDDL.DataBind()
    End Sub

    Protected Sub LoadReportButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LoadReportButton.Click
        Dim userReportId As Integer = Me.SavedReportsDDL.SelectedValue
        Dim reportList As Generic.List(Of Cdm.DataCore.AdHocReport.AdHocUserReportCriterion) = Cdm.DataCore.AdHocReport.AdHocUserReportCriterion.ListByUserReportId(userReportId)
        Dim i As Integer
        Dim chkList As CheckBoxList = CType(FieldListPane.FindControl("ColumnsCheckBoxList"), CheckBoxList)
        'Dim chkList As CheckBoxList = Me.ColumnsCheckBoxList

        Me.SearchCriteria.Clear()

        For i = 0 To reportList.Count - 1
            Dim NewCriterion As SearchCriterion = New SearchCriterion()
            NewCriterion.FieldName = reportList(i).FieldName
            NewCriterion.Operand = reportList(i).FieldOperator
            NewCriterion.FieldValue = reportList(i).FieldValue
            NewCriterion.Id = Me.SearchCriteria.Count + 1
            Me.SearchCriteria.Add(NewCriterion)
            BindGrid()
        Next

        Dim fieldList As Generic.List(Of Cdm.DataCore.AdHocReport.AdHocUserReportField) = Cdm.DataCore.AdHocReport.AdHocUserReportField.ListByUserReportId(userReportId)

        chkList.ClearSelection()

        'For Each item As ListItem In chkList.Items
        '    For i = 0 To fieldList.Count - 1
        '        If fieldList(i).FieldName = item.Text Then
        '            item.Selected = True
        '        End If
        '    Next
        'Next

        For chk As Integer = 0 To chkList.Items.Count - 1
            For i = 0 To fieldList.Count - 1
                If fieldList(i).FieldName = chkList.Items(chk).Text Then
                    Dim listItem As ListItem = chkList.Items.FindByValue(chkList.Items(chk).Value.ToString())
                    listItem.Selected = True
                End If
            Next
        Next
    End Sub

End Class